package com.dmcliver.timetracker.controller;

import java.io.Serializable;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.persistence.PersistenceException;

import org.hibernate.exception.ConstraintViolationException;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.log.Log;
import org.jboss.seam.security.Credentials;
import org.jboss.seam.security.Identity;

import com.dmcliver.timetracker.builder.PersonBuilder;
import com.dmcliver.timetracker.entity.Person;
import com.dmcliver.timetracker.persistence.PersonDAO;

@Name("registerControllerBean")
public class RegisterControllerBean implements Serializable{

	private static final long serialVersionUID = -3117460332032727747L;

	@In
	private PersonDAO personDAO;
	@In
	private Credentials credentials;
	@In 
	private Identity identity;
	@In
	private PersonBuilder personBuilder;
	@In
	private FacesContext facesContext;
	@Logger 
	private Log log;
	
	@In
	private String firstName;
	@In
	private String lastName;
	@In
	private String password;
	@In
	private String confirmPassword;
	@In
	private String userName;
	
	public String register(){
		
		//TODO: have this return the user home page
		if(identity.isLoggedIn())
			return "viewregistered";
		
		if(!formIsValid()){
			return "Error";
		}
		
		Person person = null;
		try{			
			person = personBuilder.build(userName, firstName, lastName, password);
			personDAO.persist(person);
		}
		catch(PersistenceException ex){
			
			if(ex.getCause() instanceof ConstraintViolationException)
				facesContext.addMessage("register.xhtml", new FacesMessage("Username must be unique", "Please enter in a different username"));
			else
				addUnknownError(ex);
			return "Error";
		}
		catch(Exception ex){
			
			addUnknownError(ex);
			return "Error";
		}
		
		logTheUserIn(person);
		
		return "viewregistered";
	}
	
	private boolean formIsValid() {
		
		if(!confirmPassword.equals(password)){
			facesContext.addMessage("register.xhtml", new FacesMessage(FacesMessage.SEVERITY_ERROR, "The passwords entered are different", ""));
			return false;
		}
		
		if(!password.matches("^(?=.*[^0-9a-zA-Z])(?=.*\\d)(?=.*[A-Z])\\S{8,}$")){
			facesContext.addMessage("register.xhtml", new FacesMessage(FacesMessage.SEVERITY_ERROR, "The password must contain one capital, one number and one symbol", ""));
			return false;
		}
		return true;
	}
	
	private void addUnknownError(Exception ex) {
		
		log.error("An unexcepted error occured with username: {0}, firstname: {1}, lastname: {2} & password: {3}.", ex, userName, firstName, lastName, password);
		facesContext.addMessage("register.xhtml", new FacesMessage(FacesMessage.SEVERITY_ERROR, "An unexcepted error occured trying to create your account", ""));
	}
	
	private void logTheUserIn(Person person) {
		
		credentials.setUsername(person.getUsername());
		credentials.setPassword(password);
		identity.login();
	}
}
